package com.zhisheng.core.page;

import static java.lang.Math.max;
import static java.lang.Math.min;

import java.util.ArrayList;
import java.util.List;

/**
 * @author qzhou
 */
public class Page<E> {

	public static final String SORT_ASC = "asc";
	public static final String SORT_DESC = "desc";
	
	public static final int FIRST_PAGE = 1;
	
	private int currentPage;
	private int pageSize = 10;
	private int totalRecords;
	private String sortType;
	private String sortId;
	
	private int middleLimitSide = 2;
	private int startLimitShow = 2;
	private int endLimitShow = 2;
	
	private int totalPage;
	
	private List<E> items = new ArrayList<E>();

	/**
	 * @return the startLimitShow
	 */
	public int getStartLimitShow() {
		return startLimitShow;
	}

	/**
	 * @param startLimitShow the startLimitShow to set
	 */
	public void setStartLimitShow(int startLimitShow) {
		this.startLimitShow = startLimitShow;
	}

	/**
	 * @return the endLimitShow
	 */
	public int getEndLimitShow() {
		return endLimitShow;
	}

	/**
	 * @param endLimitShow the endLimitShow to set
	 */
	public void setEndLimitShow(int endLimitShow) {
		this.endLimitShow = endLimitShow;
	}

	/**
	 * @return the middleLimitSide
	 */
	public int getMiddleLimitSide() {
		return middleLimitSide;
	}

	/**
	 * @param middleLimitSide the middleLimitSide to set
	 */
	public void setMiddleLimitSide(int middleLimitSide) {
		this.middleLimitSide = middleLimitSide;
	}

	public Page() {
		super();
	}

	public Page(int currentPage, int pageSize, int totalRecords) {
		super();
		this.currentPage = currentPage;
		this.pageSize = pageSize;
		this.totalRecords = totalRecords;
		
		this.totalPage = getTotalPage();
	}

	public int getCurrentPage() {
		return currentPage;
	}

	public void setCurrentPage(int currentPage) {
		this.currentPage = currentPage;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getTotalRecords() {
		return totalRecords;
	}

	public void setTotalRecords(int totalRecords) {
		this.totalRecords = totalRecords;
	}

	public List<E> getItems() {
		return items;
	}

	public void setItems(List<E> items) {
		this.items = items;
	}
	
	public int getTotalPage() {
		if(this.totalPage == 0) {
			if(this.pageSize == 0)
				return 0;
			
			this.totalPage = this.totalRecords / this.pageSize + 
				(this.totalRecords % this.pageSize == 0 ? 0 : 1);
		}
		
		return this.totalPage;
	}
	
	public boolean isPrePage() {
		return this.currentPage > FIRST_PAGE;
	}
	
	public boolean isNextPage() {
		return this.currentPage < this.getTotalPage();
	}
	
	public int getListStartIndex() {
		if(this.currentPage > this.getTotalPage()) {
			this.currentPage = Math.max(1, this.getTotalPage());
		}
		return (this.currentPage - 1) * this.pageSize;
	}
	
	public int getListEndIndex() {
		return Math.min(totalRecords, currentPage * pageSize);
	}

	public String getSortType() {
		return sortType;
	}

	public void setSortType(String sortType) {
		this.sortType = sortType;
	}

	public String getSortId() {
		return sortId;
	}

	public void setSortId(String sortId) {
		this.sortId = sortId;
	}

	public List<List<Integer>> getShowPageNums() {
		List<List<Integer>> list = new ArrayList<List<Integer>>();
		List<Integer> sList = new ArrayList<Integer>();
		
		int from1 = 1;
		int to1 = min(startLimitShow, getTotalPage());
		for(int i = from1; i <= to1; i++)
			sList.add(i);
		
		int from2 = max(to1 + 1, min(currentPage - middleLimitSide, getTotalPage() - middleLimitSide * 2));
		int to2 = min(max(currentPage + middleLimitSide, middleLimitSide * 2 + 1), getTotalPage() - endLimitShow);
		if(min(from2, to2) - max(from1, to1) > 1) {
			list.add(sList);
			sList = new ArrayList<Integer>();
		}
		
		for(int i = from2; i <= to2; i++)
			sList.add(i);
		
		int from3 = max(max(from2, to2 + 1), getTotalPage() - endLimitShow + 1);
		int to3 = getTotalPage();
		if(min(from3, to3) - max(to2, from2) > 1) {
			list.add(sList);
			sList = new ArrayList<Integer>();
		}
		for(int i = from3; i <= to3; i++)
			sList.add(i);
		list.add(sList);
		
		return list;
	}

	public static void main(String[] args) {
		int i = 1;
		int j = 1;
		int k = 1;
		for(k = 1; k <= 20; k++) {
			for(i = 1; i <= k; i++) {
				Page<Integer> page = new Page<Integer>(i, j, k);
				System.out.println(page.getShowPageNums());
			}
		}
	}
}
